<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
</body>
<script>
let order = function(orderType, pay, stock) {
  if(orderType === 1) {
    if(pay === true) {
      console.log('500定金预购，得到100优惠券');
    } else {
      if(stock > 0) {
        console.log('普通购买，无优惠券');
      } else {
        console.log('手机库存不足');
      }
    }
  } else
  if(orderType === 2) {
    if(pay === true) {
      console.log('200定金预购，得到50优惠券');
    } else {
      if(stock > 0) {
        console.log('普通购买，无优惠券');
      } else {
        console.log('手机库存不足');
      }
    }
  } else
  if(orderType === 3) {
    if(stock > 0) {
      console.log('普通购买，无优惠券');
    } else {
      console.log('手机库存不足');
    }
  }
}

// 职责链模式
let order500 = function(orderType, pay, stock) {
  if(orderType === 1 && pay === true) {
    console.log('500定金预购，得到100优惠券');
  } else {
    order200(orderType, pay, stock)
  }
}
let order200 = function(orderType, pay, stock) {
  if(orderType === 2 && pay === true) {
    console.log('200定金预购，得到50优惠券');
  } else {
    orederNormal(orderType, pay, stock)
  }
}
let orderNormal = function(orderType, pay, stock) {
  if(stock > 0) {
    console.log('普通购买，无优惠券');
  } else {
    console.log('手机库存不足');
  }
}
// test
order500(1, true, 500); // 输出：500 元定金预购, 得到 100 优惠券
order500(1, false, 500); // 输出：普通购买, 无优惠券
order500(2, true, 500); // 输出：200 元定金预购, 得到 50 优惠券
order500(3, false, 500); // 输出：普通购买, 无优惠券
order500(3, false, 0); // 输出：手机库存不足

// 可灵活拆分的职责链节点
let order500 = function(orderType, pay, stock) {
  if(orderType === 1 && pay === true) {
    console.log('500定金预购，得到100优惠券');
  } else {
    return 'nextSuccessor';
  }
}
let order200 = function(orderType, pay, stock) {
  if(orderType === 2 && pay === true) {
    console.log('200定金预购，得到50优惠券');
  } else {
    return 'nextSuccessor';
  }
}
let orderNormal = function(orderType, pay, stock) {
  if(stock > 0) {
    console.log('普通购买，无优惠券');
  } else {
    console.log('手机库存不足');
  }
}
// 定义包装函数
class Chain {
  constructor(fn) {
    this.fn = fn;
    this.successor = null;
  }
  setNextSuccessor(successor) {
    return this.successor = successor;
  }
  passRequest() {
    let ret = this.fn.apply(this, arguments);
    if(ret === 'nextSuccessor') {
      return this.successor && this.successor.passRequest.apply(this.successor, arguments);
    }
    return ret;
  }
  next() {
    return this.successor && this.successor.passRequest.apply(this.successor, arguments);
  }
}
// 包装函数 -> 职责链节点
let chainOrder500 = new Chain(order500)
let chainOrder200 = new Chain(order200)
let chainOrderNormal = new Chain(orderNormal)
// 指定节点在职责链中的顺序
chainOrder500.setNextSuccessor(chainOrder200)
chainOrder200.setNextSuccessor(chainOrderNormal)
// 将请求传递给第一个节点
chainOrder500.passRequest( 1, true, 500 ); // 输出：500 元定金预购，得到 100 优惠券
chainOrder500.passRequest( 2, true, 500 ); // 输出：200 元定金预购，得到 50 优惠券
chainOrder500.passRequest( 3, true, 500 ); // 输出：普通购买，无优惠券
chainOrder500.passRequest( 1, false, 0 ); // 输出：手机库存不足

let fn1 = new Chain(() => {
  console.log(1);
  return 'nextSuccessor'
})
let fn2 = new Chain(() => {
  console.log(2);
  setTimeout(() => {
    fn2.next()
  }, 1000)
})
let fn3 = new Chain(() => {
  console.log(3);
})
fn1.setNextSuccessor(fn2).setNextSuccessor(fn3)
fn1.passRequest()

Function.prototype.after = fn => {
  let _self = this
  return function() {
    let ret = _self.apply(this, arguments)
    if(ret === 'nextSuccessor') {
      return fn.apply(this, arguments)
    }
    return ret
  }
}

</script>
</html>